import { createElement, onDestroy } from "../../../lib/skeleton/index.js";
import { OrbitControls } from "../../../lib/vendor/three/OrbitControls.js";

export default function({ THREE, $page, $menubar, mesh, refresh, is2D, background }) {
    // setup the dom
    const renderer = new THREE.WebGLRenderer({ antialias: true, shadowMapEnabled: true });
    renderer.shadowMap.enabled = true;
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    renderer.setClearColor(0xf5f5f5);
    renderer.setSize($page.clientWidth, $page.clientHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
    $page.appendChild(renderer.domElement);

    // center everything
    const box = new THREE.Box3().setFromObject(mesh);
    const center = box.getCenter(new THREE.Vector3());
    const size = box.getSize(new THREE.Vector3());
    const maxDim = Math.max(size.x, size.y, size.z);

    // setup the scene, camera and controls
    const scene = new THREE.Scene();
    scene.background = new THREE.Color(background);
    const camera = new THREE.PerspectiveCamera(
        45,
        $page.clientWidth / $page.clientHeight,
        Math.max(0.1, maxDim / 100),
        maxDim * 1000,
    );
    const controls = new OrbitControls(camera, renderer.domElement);
    if (is2D()) {
        controls.zoomToCursor = true;
        controls.enableRotate = false;
        controls.mouseButtons = {
            LEFT: THREE.MOUSE.PAN,
            MIDDLE: THREE.MOUSE.DOLLY,
            RIGHT: THREE.MOUSE.ORBIT
        };
    }

    scene.add(mesh);
    mesh.castShadow = true;
    mesh.receiveShadow = true;
    camera.position.set(center.x, center.y, center.z + maxDim * (is2D() ? 1.3 : 1.8));
    controls.target.copy(center);

    const mixer = new THREE.AnimationMixer(mesh);
    if (mesh.animations.length > 0) {
        const ICON = {
            PLAY: "",
            PAUSE: "",
        };
        const $button = createElement(`<img class="component_icon" draggable="false" src="${ICON.PLAY}" alt="play">`);
        const action = mixer.clipAction(mesh.animations[0]);
        let isPlaying = false;
        $button.onclick = () => {
            if (isPlaying === false) action.play();
            else action.stop();
            isPlaying = !isPlaying;
            $button.setAttribute("src", isPlaying ? ICON.PAUSE : ICON.PLAY);
        };
        $menubar.add($button);
    }

    const onResize = () => {
        camera.aspect = $page.clientWidth / $page.clientHeight;
        camera.updateProjectionMatrix();
        renderer.setSize($page.clientWidth, $page.clientHeight);
    };
    window.addEventListener("resize", onResize);
    onDestroy(() => window.removeEventListener("resize", onResize));

    const clock = new THREE.Clock();
    refresh.push(() => {
        controls.update();
        renderer.render(scene, camera);
        mixer.update(clock.getDelta());
    });

    return { renderer, scene, camera, controls, box };
}
